#![allow(dead_code, mutable_transmutes, non_camel_case_types, non_snake_case, non_upper_case_globals, unused_assignments, unused_mut)]
use std::mem;
use crate::alloc_testing::*;
extern "C" {
    fn memmove(
        _: *mut libc::c_void,
        _: *const libc::c_void,
        _: libc::c_ulong,
    ) -> *mut libc::c_void;
            }
pub type size_t = libc::c_ulong;
pub type ArrayListValue = *mut libc::c_void;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _ArrayList {
    pub data: *mut ArrayListValue,
    pub length: libc::c_uint,
    pub _alloced: libc::c_uint,
}
pub type ArrayList = _ArrayList;
pub type ArrayListEqualFunc = Option::<
    unsafe extern "C" fn(ArrayListValue, ArrayListValue) -> libc::c_int,
>;
pub type ArrayListCompareFunc = Option::<
    unsafe extern "C" fn(ArrayListValue, ArrayListValue) -> libc::c_int,
>;
#[no_mangle]
pub extern "C" fn arraylist_new(mut length: libc::c_uint) -> *mut ArrayList {
    if length == 0 {
        length = 16;
    }

    let new_arraylist: *mut ArrayList = unsafe {
        alloc_test_malloc(std::mem::size_of::<ArrayList>() as libc::c_ulong) as *mut ArrayList
    };
    if new_arraylist.is_null() {
        return std::ptr::null_mut();
    }

    let mut boxed_arraylist = unsafe { Box::from_raw(new_arraylist) };
    boxed_arraylist._alloced = length;
    boxed_arraylist.length = 0;
    boxed_arraylist.data = unsafe {
        alloc_test_malloc(
            (length as libc::c_ulong).wrapping_mul(std::mem::size_of::<ArrayListValue>() as libc::c_ulong)
        ) as *mut ArrayListValue
    };

    if boxed_arraylist.data.is_null() {
        alloc_test_free(new_arraylist as *mut libc::c_void);
        return std::ptr::null_mut();
    }

    let new_arraylist = Box::into_raw(boxed_arraylist);
    new_arraylist
}
#[no_mangle]
pub extern "C" fn arraylist_free(mut arraylist: *mut ArrayList) {
    if !arraylist.is_null() {
        let boxed_arraylist = unsafe { Box::from_raw(arraylist) };
        unsafe {
            alloc_test_free(boxed_arraylist.data as *mut libc::c_void);
            alloc_test_free(arraylist as *mut libc::c_void);
        }
        let arraylist = Box::into_raw(boxed_arraylist);
    }
}
extern "C" fn arraylist_enlarge(mut arraylist: *mut ArrayList) -> libc::c_int {
    let mut boxed_arraylist = unsafe { Box::from_raw(arraylist) };
    let mut data: *mut ArrayListValue = std::ptr::null_mut();
    let mut newsize: libc::c_uint = 0;

    newsize = boxed_arraylist._alloced.wrapping_mul(2);
    data = unsafe {
        alloc_test_realloc(
            boxed_arraylist.data as *mut libc::c_void,
            (std::mem::size_of::<ArrayListValue>() as libc::c_ulong)
                .wrapping_mul(newsize as libc::c_ulong),
        ) as *mut ArrayListValue
    };

    if data.is_null() {
        arraylist = Box::into_raw(boxed_arraylist);
        return 0;
    } else {
        boxed_arraylist.data = data;
        boxed_arraylist._alloced = newsize;
        arraylist = Box::into_raw(boxed_arraylist);
        return 1;
    }
}
#[no_mangle]
pub extern "C" fn arraylist_insert(
    mut arraylist: *mut ArrayList,
    mut index: libc::c_uint,
    mut data: ArrayListValue,
) -> libc::c_int {
    let mut boxed_arraylist = unsafe { Box::from_raw(arraylist) };
    let length = boxed_arraylist.length;
    if index > length {
        arraylist = Box::into_raw(boxed_arraylist);
        return 0;
    }

    let alloced = boxed_arraylist._alloced;
    if length.wrapping_add(1) > alloced {
        if arraylist_enlarge(arraylist) == 0 {
            arraylist = Box::into_raw(boxed_arraylist);
            return 0;
        }
    }

    let data_ptr = boxed_arraylist.data;
    unsafe {
        memmove(
            data_ptr.offset(index.wrapping_add(1) as isize) as *mut libc::c_void,
            data_ptr.offset(index as isize) as *const libc::c_void,
            (length.wrapping_sub(index) as libc::c_ulong)
                .wrapping_mul(std::mem::size_of::<ArrayListValue>() as libc::c_ulong),
        );
        *data_ptr.offset(index as isize) = data;
        boxed_arraylist.length = length.wrapping_add(1);
    }

    arraylist = Box::into_raw(boxed_arraylist);
    return 1;
}
#[no_mangle]
pub extern "C" fn arraylist_append(
    mut arraylist: *mut ArrayList,
    mut data: ArrayListValue,
) -> libc::c_int {
    let boxed_arraylist = unsafe { Box::from_raw(arraylist) };
    let result = arraylist_insert(arraylist, boxed_arraylist.length, data);
    arraylist = Box::into_raw(boxed_arraylist);
    result
}
#[no_mangle]
pub extern "C" fn arraylist_prepend(
    mut arraylist: *mut ArrayList,
    mut data: ArrayListValue,
) -> libc::c_int {
    let boxed_arraylist = unsafe { Box::from_raw(arraylist) };
    let result = arraylist_insert(arraylist, 0, data);
    arraylist = Box::into_raw(boxed_arraylist);
    result
}
#[no_mangle]
pub extern "C" fn arraylist_remove_range(
    mut arraylist: *mut ArrayList,
    mut index: libc::c_uint,
    mut length: libc::c_uint,
) {
    let mut boxed_arraylist = unsafe { Box::from_raw(arraylist) };
    if index > boxed_arraylist.length || index.wrapping_add(length) > boxed_arraylist.length {
        arraylist = Box::into_raw(boxed_arraylist);
        return;
    }
    unsafe {
        memmove(
            &mut *boxed_arraylist.data.offset(index as isize) as *mut ArrayListValue
                as *mut libc::c_void,
            &mut *boxed_arraylist.data.offset(index.wrapping_add(length) as isize)
                as *mut ArrayListValue as *const libc::c_void,
            ((boxed_arraylist.length).wrapping_sub(index.wrapping_add(length)) as libc::c_ulong)
                .wrapping_mul(std::mem::size_of::<ArrayListValue>() as libc::c_ulong),
        );
    }
    boxed_arraylist.length = boxed_arraylist.length.wrapping_sub(length);
    arraylist = Box::into_raw(boxed_arraylist);
}
#[no_mangle]
pub extern "C" fn arraylist_remove(
    mut arraylist: *mut ArrayList,
    mut index: libc::c_uint,
) {
    let boxed_arraylist = unsafe { Box::from_raw(arraylist) };
    arraylist_remove_range(arraylist, index, 1);
    let arraylist = Box::into_raw(boxed_arraylist);
}
#[no_mangle]
pub extern "C" fn arraylist_index_of(
    mut arraylist: *mut ArrayList,
    mut callback: ArrayListEqualFunc,
    mut data: ArrayListValue,
) -> libc::c_int {
    let boxed_arraylist = unsafe { Box::from_raw(arraylist) };
    let mut i: libc::c_uint = 0;
    i = 0;
    while i < boxed_arraylist.length {
        if unsafe {
            callback
                .expect("non-null function pointer")
                (*boxed_arraylist.data.offset(i as isize), data)
        } != 0 {
            arraylist = Box::into_raw(boxed_arraylist);
            return i as libc::c_int;
        }
        i = i.wrapping_add(1);
    }
    arraylist = Box::into_raw(boxed_arraylist);
    return -1;
}
#[no_mangle]
pub extern "C" fn arraylist_clear(mut arraylist: *mut ArrayList) {
    let mut boxed_arraylist = unsafe { Box::from_raw(arraylist) };
    boxed_arraylist.length = 0;
    arraylist = Box::into_raw(boxed_arraylist);
}
extern "C" fn arraylist_sort_internal(
    mut list_data: *mut ArrayListValue,
    mut list_length: libc::c_uint,
    mut compare_func: ArrayListCompareFunc,
) {
    if list_length <= 1 {
        return;
    }

    let mut pivot: ArrayListValue;
    let mut tmp: ArrayListValue;
    let mut i: libc::c_uint = 0;
    let mut list1_length: libc::c_uint = 0;
    let mut list2_length: libc::c_uint;

    unsafe {
        pivot = *list_data.offset(list_length.wrapping_sub(1) as isize);
    }

    while i < list_length.wrapping_sub(1) {
        unsafe {
            if compare_func.expect("non-null function pointer")(*list_data.offset(i as isize), pivot) < 0 {
                tmp = *list_data.offset(i as isize);
                *list_data.offset(i as isize) = *list_data.offset(list1_length as isize);
                *list_data.offset(list1_length as isize) = tmp;
                list1_length = list1_length.wrapping_add(1);
            }
        }
        i = i.wrapping_add(1);
    }

    list2_length = list_length.wrapping_sub(list1_length).wrapping_sub(1);

    unsafe {
        *list_data.offset(list_length.wrapping_sub(1) as isize) = *list_data.offset(list1_length as isize);
        *list_data.offset(list1_length as isize) = pivot;
    }

    unsafe {
        arraylist_sort_internal(list_data, list1_length, compare_func);
        arraylist_sort_internal(
            &mut *list_data.offset(list1_length.wrapping_add(1) as isize),
            list2_length,
            compare_func,
        );
    }
}
#[no_mangle]
pub extern "C" fn arraylist_sort(
    mut arraylist: *mut ArrayList,
    mut compare_func: ArrayListCompareFunc,
) {
    let boxed_arraylist = unsafe { Box::from_raw(arraylist) };
    arraylist_sort_internal(boxed_arraylist.data, boxed_arraylist.length, compare_func);
    let arraylist = Box::into_raw(boxed_arraylist);
}
